<template>
	<view class="e-drag-list-item" :style="[itemStyle]">
		<view class="e-drag-list-item__content" v-show="!moveState">
			<view class="e-drag-list-item__content-left">
				<slot>
					<view>
						<text class="e-drag-list-item__content-left__label" v-if="props.label">{{ props.label }}</text>
					</view>
				</slot>
			</view>
			<view :data-parentsId="dragListContext.id" :data-id="elId" :data-sort="sortNumber" @touchstart="drag.touchstart" @touchmove="drag.touchmove" @touchend="drag.touchend">
				<slot name="icon">
					<e-icon :name="dragListContext.props.icon" :color="dragListContext.props.iconColor" :size="dragListContext.props.iconSize"></e-icon>
				</slot>
			</view>
		</view>
		<e-line :color="dragListContext.props.borderColor" v-if="borderShow"></e-line>
	</view>
</template>

<script src="../e-drag-list/drag.wxs" module="drag" lang="wxs"></script>

<script lang="ts">
import { defineComponent } from 'vue';
import mpMixin from '../../libs/mixin/mpMixin';
/**
 * @property {String|Number} 		index					组件索引
 * @property {Boolean} 				disabled				是否禁用 （默认 false）
 * @property {String} 				label					左侧文本
 */
export default defineComponent({
	name: 'e-drag-list-item',
	mixins: [mpMixin],
	methods: {
		// uniapp wxs的callMethod不支持setup写法，改为自定义callMethod
		callMethod([e,params]:[string,any]) {
			this._.exposed[e]?.(params);
		}
	}
});
</script>

<script lang="ts">
import { ref, reactive, computed, watch, toRefs, inject, onUnmounted, defineComponent } from 'vue';
import mpMixin from '../../libs/mixin/mpMixin';
import { useDefaultProps } from '../../libs/hooks';
import { dragListItemProps, dragListItemEmits } from './props';
import { dragListContextKey } from '../../libs/tokens';
import { nanoid } from '../../libs/utils';
import { addUnit, throwError } from '../../libs/utils/_utils';
import componentsProps from '../../libs/config/componentsProps';
import { type DragListItemProps } from '../../libs/config/propsType';
import type { StyleProperties } from '../../libs/tokens';

export default defineComponent({
	props: dragListItemProps,
	emit: dragListItemEmits,
	setup(props, ctx) {
		const { dragListItem: dragListItemDefaultProps } = toRefs(componentsProps);

		const _props = useDefaultProps<DragListItemProps>(props, dragListItemDefaultProps);

		const dragListContext = inject(dragListContextKey);
		if (!dragListContext) throwError('EDragListItem', 'e-drag-list-item需要结合e-drag-list组件使用');

		const elDisabled = computed(() => dragListContext.props.disabled || _props.value.disabled);
		const elId = ref(nanoid(21, true));
		// 记录组件是否正在被拖动，是则隐藏组件
		const sortNumber = ref(Number(_props.value.index));
		const moveSort = ref(sortNumber.value);
		const updateMoveSort = (value: number) => {
			moveSort.value = value;
		};
		const updateSort = (value: number) => {
			sortNumber.value = value;
			updateMoveSort(value);
		};

		watch(
			() => _props.value.index,
			(v: string) => {
				updateSort(Number(v));
			}
		);

		const context = reactive({
			uid: elId,
			index: _props.value.index,
			sortNumber,
			props: _props,
			updateSort,
			updateMoveSort
		});

		const itemStyle = computed(() => {
			let sort = sortNumber.value;
			let style: StyleProperties = {
				height: addUnit(dragListContext.props.itemHeight)
			};
			if (dragListContext.isMove) {
				style.transition = 'transform 0.2s';
				style['-webkit-transition'] = 'transform 0.2s';
				sort = moveSort.value;
			}
			style.transform = 'translate3d(0,' + (sort - Number(_props.value.index)) * 100 + '%,-1px)';
			return style;
		});

		const borderShow = computed(() => dragListContext.props.borderBottom && _props.value.index !== dragListContext.length - 1);

		const moveState = ref(false);

		const moveStart = (e: { top: number }) => {
			if (elDisabled.value) return;
			dragListContext?.showDragEl(elId.value, e.top);
			moveState.value = true;
		};
		const move = (e: { top: number }) => {
			if (elDisabled.value) return;
			dragListContext?.handleMove(e.top);
		};
		const moveEnd = () => {
			if (elDisabled.value) return;
			moveState.value = false;
			dragListContext?.hiddDragEl();
		};

		const handlePageScroll = (e: any) => {
			if (elDisabled.value) return;
			dragListContext?.pageScroll(e);
		};
		const updateRowsSort = (e: { uid: string; sort: number }) => {
			if (elDisabled.value) return;
			dragListContext?.updateChildSort(e.uid, e.sort);
		};
		const sortChange = (e) => {
			if (elDisabled.value) return;
			dragListContext?.updateRowsSort(e.sortList);
		};
		// 初始化数据
		dragListContext?.addField(context);
		onUnmounted(() => {
			dragListContext.removeField(elId.value);
		});
		
		ctx.expose({
			handlePageScroll,
			moveStart,
			moveEnd,
			sortChange,
			move,
			updateRowsSort,
			vibrate
		})

		return {
			props: _props,
			sortNumber,
			dragListContext,
			elId,
			itemStyle,
			borderShow,
			moveState,
			moveStart,
			move,
			moveEnd,
			handlePageScroll,
			updateRowsSort,
			sortChange
		};
	}
});
</script>

<style lang="scss" scoped>
@import '../../libs/theme/drag-list-item.scss';
</style>
